package org.kenewstar.user.controller;

import org.kenewstar.common.bean.pojo.MicroUser;
import org.kenewstar.common.constant.CommonConstant;
import org.kenewstar.common.utils.AssertUtil;
import org.kenewstar.common.utils.CommonResult;
import org.kenewstar.common.utils.CommonUtil;
import org.kenewstar.user.dto.*;
import org.kenewstar.user.service.UserService;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.ArrayList;
import java.util.Objects;

/**
 * 用户控制器
 * @author xinke.huang@hand-china.com
 * @version 1.0
 * @date 2021/2/27
 */
@RestController
@CrossOrigin(value={CommonConstant.API_HOST},
        allowCredentials = "true",
        methods = {RequestMethod.OPTIONS, RequestMethod.GET, RequestMethod.POST},
        maxAge = 86400)
public class UserController {

    @Resource
    private UserService userService;
    @Resource
    private RedisTemplate<String, String> redisTemplate;

    /**
     * 用户登录
     * @param user 登录参数
     * @return 返回统一结果
     */
    @RequestMapping("/userLogin")
    public CommonResult userLogin(@RequestBody MicroUser user, HttpServletRequest request) {
        AssertUtil.notNull(user.getEmail());
        AssertUtil.notNull(user.getPassword());
        HttpSession session = request.getSession();
        // 获取指定用户信息
        MicroUser microUser = userService.getUserByEmail(user.getEmail());
        if (Objects.isNull(microUser)){
            // 用户名或密码错误
            return CommonResult.failed("用户名或密码错误");
        }
        // 将密码加密
        String md5Pwd = CommonUtil.md5(microUser.getUsername(), user.getPassword());
        // 密码比较
        if (!Objects.equals(md5Pwd, microUser.getPassword())) {
            // 用户名或密码错误
            return CommonResult.failed("用户名或密码错误");
        }
        // 登录成功
        session.setAttribute(CommonConstant.SESSION_USER, microUser);
        // 返回用户信息
        return CommonResult.success(microUser);
    }

    /**
     * 用户退出登录
     * @param session 会话
     * @return 消息
     */
    @PostMapping("/logout")
    public CommonResult userLogout(HttpSession session){
        // 销毁session
        session.removeAttribute(CommonConstant.SESSION_USER);
        return CommonResult.success();
    }

    /**
     * 检查登录
     * @return result
     */
    @RequestMapping("/check")
    public CommonResult checkLogin(){
        return CommonResult.success();
    }

    /**
     * 获取用户信息
     * @param session session会话
     * @return 用户信息
     */
    @GetMapping("/myInfo")
    public CommonResult myInfo(HttpSession session) {
        MicroUser user = (MicroUser)session.getAttribute(CommonConstant.SESSION_USER);
        if (Objects.isNull(user)) {
            return CommonResult.failed();
        }
        user.setAvatar(userService.getAvatar(user.getId()));
        return CommonResult.success(user);
    }

    /**
     * 校验url的存在
     * @param dto url参数
     * @return 校验结果
     */
    @PostMapping("/validate/url")
    public CommonResult validateShareUrl(@RequestBody ValidShareUrlDto dto) {
        AssertUtil.notNull(dto);
        ValidShareUrlReturnDto returnDto = userService.validateShareUrl(dto.getUrl());
        if (Objects.nonNull(returnDto)) {
            return CommonResult.success(returnDto);
        }
        return CommonResult.failed();
    }

    /**
     * 上传头像
     * @param dto 参数
     * @param session 用户session
     * @return result
     */
    @PostMapping("/upload/avatar")
    public CommonResult uploadAvatar(@RequestBody UploadAvatarDto dto, HttpSession session) {
        AssertUtil.notNull(dto);
        MicroUser user = (MicroUser) session.getAttribute(CommonConstant.SESSION_USER);
        userService.uploadAvatar(dto.getAvatar(), user.getId());
        return CommonResult.success();
    }

    /**
     * 用户注册
     * @param register 注册信息
     * @return result
     */
    @PostMapping("/register")
    public CommonResult userRegister(@RequestBody RegisterDto register) {
        // 校验字段
        AssertUtil.notNull(register);
        MicroUser user = userService.getUserByEmail(register.getEmail());
        if (Objects.nonNull(user)) {
            return CommonResult.failed("该用户已注册");
        }
        // 获取key
        String cacheKey = CommonUtil.getCacheKey(CommonConstant.CachePrefix.REGISTER, register.getEmail());
        // 校验 验证码是否正确
        String code = redisTemplate.opsForValue()
                .get(cacheKey);
        if (!Objects.equals(code, register.getCode())) {
            return CommonResult.failed("验证码错误");
        }
        // 发起注册操起
        // 加密密码
        String username = CommonUtil.generateUsername();
        String md5Pwd = CommonUtil.md5(username, register.getPassword());
        MicroUser registerUser = new MicroUser();
        registerUser.setUsername(username);
        registerUser.setPassword(md5Pwd);
        registerUser.setEmail(register.getEmail());
        // 注册
        userService.userRegister(registerUser);
        // 移除redis中的code
        redisTemplate.delete(cacheKey);
        return CommonResult.success();
    }

    /**
     * 更新用户信息
     * @param user 用户参数
     * @param session 用户对象
     * @return result
     */
    @PostMapping("/update/user")
    public CommonResult updateUser(@RequestBody MicroUser user, HttpSession session) {
        // 校验
        MicroUser sessionUser = (MicroUser) session.getAttribute(CommonConstant.SESSION_USER);
        user.setId(sessionUser.getId());
        // 更新用户
        int rows = userService.updateUserById(user);
        updateSessionUser(user, sessionUser);
        session.setAttribute(CommonConstant.SESSION_USER, sessionUser);
        return CommonResult.success(rows);
    }

    /**
     * 更新sessionUser
     * @param user 更新数据
     * @param sessionUser sessionUser
     */
    private void updateSessionUser(MicroUser user,MicroUser sessionUser) {
        if (Objects.nonNull(user.getUsername())) {
            sessionUser.setUsername(user.getUsername());
        }
        if (Objects.nonNull(user.getPassword())) {
            sessionUser.setPassword(user.getPassword());
        }
        if (Objects.nonNull(user.getNickname())) {
            sessionUser.setNickname(user.getNickname());
        }
        if (Objects.nonNull(user.getDiskSize())) {
            sessionUser.setDiskSize(user.getDiskSize());
        }
        if (Objects.nonNull(user.getEmail())) {
            sessionUser.setEmail(user.getEmail());
        }
        if (Objects.nonNull(user.getPhone())) {
            sessionUser.setPhone(user.getPhone());
        }
        if (Objects.nonNull(user.getStatus())) {
            sessionUser.setStatus(user.getStatus());
        }
    }

    /**
     * 修改密码操作
     * @param dto  修改密码参数
     * @param session session对象
     * @return result
     */
    @PostMapping("/update/pwd")
    public CommonResult updatePwd(@RequestBody UpdatePwdDto dto, HttpSession session) {
        AssertUtil.notNull(dto);
        // 获取用户
        MicroUser user = (MicroUser) session.getAttribute(CommonConstant.SESSION_USER);
        if (!Objects.equals(user.getEmail(), dto.getEmail())) {
            return CommonResult.failed("邮箱账号错误");
        }
        // 获取key
        String cacheKey = CommonUtil.getCacheKey(CommonConstant.CachePrefix.UPDATE, user.getUsername());
        // 根据key获取验证码
        String cacheCode = redisTemplate.opsForValue().get(cacheKey);
        if (!Objects.equals(cacheCode, dto.getCode())) {
            return CommonResult.failed("验证码错误");
        }
        // 验证码正确
        MicroUser paramUser = new MicroUser();
        paramUser.setId(user.getId());
        paramUser.setPassword(CommonUtil.md5(user.getUsername(), dto.getPwd()));
        int rows = userService.updateUserById(paramUser);
        // 移除cacheCode
        redisTemplate.delete(cacheKey);
        // 移除session
        session.removeAttribute(CommonConstant.SESSION_USER);
        return CommonResult.success(rows);
    }

    /**
     * 重置密码
     * @param dto 参数
     * @return result
     */
    @PostMapping("/reset/pwd")
    public CommonResult resetPwd(@RequestBody ResetPwdDto dto) {
        AssertUtil.notNull(dto);
        // 获取缓存key
        String cacheKey = CommonUtil.getCacheKey(CommonConstant.CachePrefix.FORGET, dto.getEmail());
        // 获取缓存参数
        String param = redisTemplate.opsForValue().get(cacheKey);
        if (Objects.isNull(param)) {
            return CommonResult.failed("链接已失效");
        }
        if (!Objects.equals(param, dto.getParam())) {
            return CommonResult.failed("链接错误，请检查链接是否有误");
        }
        // 校验已通过
        // 根据邮箱获取用户信息
        MicroUser user = userService.getUserByEmail(dto.getEmail());
        MicroUser updatedUser = new MicroUser();
        updatedUser.setId(user.getId());
        updatedUser.setPassword(CommonUtil.md5(user.getUsername(), dto.getPwd()));
        int row = userService.updateUserById(updatedUser);
        redisTemplate.delete(cacheKey);
        return CommonResult.success(row);
    }

}
